﻿﻿using MySoftLab.DapFlash.Models;
using System.Collections.ObjectModel;
using Avalonia.Controls;
using MySoftLab.DapFlash.Views;
using ReactiveUI;
using Avalonia.ReactiveUI;
using System.Reactive.Linq;
using System.Reactive;
using System.Threading.Tasks;
using Avalonia.Platform.Storage;
using Avalonia.Controls.ApplicationLifetimes;
using System.Linq;
using System;
using Avalonia.Interactivity;
using System.IO;
using System.Text.Json;
using MySoftLab.DapFlashCore.Targets.Packs;
using System.Collections.Generic;
using MySoftLab.DapFlashCore.Targets;
using MySoftLab.DapFlashCore.CoreSight;
using MySoftLab.DapFlashCore.Flash;
using MySoftLab.DapFlashCore.Probes.DapAccess;
using System.Threading;
using System.Reflection;
using AvaloniaHex;
using AvaloniaHex.Document;

namespace MySoftLab.DapFlash.ViewModels
{
    public partial class MainWindowViewModel : ViewModelBase
    {
        public ReactiveCommand<Unit, Task> DownloadCommand { get; }

        public Interaction<Unit, string?> ShowFileSelectDialog { get; }

        private string _selectedFilePath = "";
        public string SelectedFilePath
        {
            get => _selectedFilePath;
            set => this.RaiseAndSetIfChanged(ref _selectedFilePath, value);
        }

        public ReactiveCommand<Unit, Task> OpenFileCommand { get; }

        private string _programAddress = "0x8000000";
        public string ProgramAddress
        {
            get => _programAddress;
            set => this.RaiseAndSetIfChanged(ref _programAddress, value);
        }

        private bool _isProgramAddressReadOnly = true;
        public bool IsProgramAddressReadOnly
        {
            get => _isProgramAddressReadOnly;
            set => this.RaiseAndSetIfChanged(ref _isProgramAddressReadOnly, value);
        }

        private const string INDEX_FILE_NAME = "targets_index.json";
        private readonly string _packsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "packs");
        private readonly string _indexFilePath;
        private Dictionary<string, string> _targetIndex = new(); // targetName -> packPath

        private string _logText = "";
        public string LogText
        {
            get => _logText;
            set => this.RaiseAndSetIfChanged(ref _logText, value);
        }

        private ulong _baseAddress = 0;

        public ulong BaseAddress
        {
            get { return _baseAddress; }
            set { this.RaiseAndSetIfChanged(ref _baseAddress, value); }
        }

        private void AppendLog(string message)
        {
            LogText += $"{message}\n";
        }

        private void ClearLog()
        {
            LogText = "";
        }

        private readonly AppSettings _settings;

        public ReactiveCommand<Unit, Task> EraseChipCommand { get; }

        private bool _isAdvancedMode;
        public bool IsAdvancedMode
        {
            get => _isAdvancedMode;
            set => this.RaiseAndSetIfChanged(ref _isAdvancedMode, value);
        }

        public ReactiveCommand<Unit, Unit> SwitchModeCommand { get; }

        private byte[]? _fileContent;
        public byte[]? FileContent
        {
            get => _fileContent;
            set => this.RaiseAndSetIfChanged(ref _fileContent, value);
        }

        private bool _isFileLoaded;
        public bool IsFileLoaded
        {
            get => _isFileLoaded;
            set => this.RaiseAndSetIfChanged(ref _isFileLoaded, value);
        }

        private IBinaryDocument? _document;
        public IBinaryDocument? Document
        {
            get => _document;
            set => this.RaiseAndSetIfChanged(ref _document, value);
        }

        private uint _parsedProgramAddress;
        public uint ParsedProgramAddress
        {
            get => _parsedProgramAddress;
            private set => this.RaiseAndSetIfChanged(ref _parsedProgramAddress, value);
        }

        private bool TryParseProgramAddress(string input, out uint result)
        {
            input = input.Trim();
            if (input.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
            {
                input = input.Substring(2);
            }
            return uint.TryParse(input, System.Globalization.NumberStyles.HexNumber, null, out result);
        }

        private string? _selectedTarget;
        public string? SelectedTarget
        {
            get => _selectedTarget;
            set => this.RaiseAndSetIfChanged(ref _selectedTarget, value);
        }

        private bool _isDownloading;
        public bool IsDownloading
        {
            get => _isDownloading;
            set => this.RaiseAndSetIfChanged(ref _isDownloading, value);
        }

        private double _downloadProgress;
        public double DownloadProgress
        {
            get => _downloadProgress;
            set => this.RaiseAndSetIfChanged(ref _downloadProgress, value);
        }

        public MainWindowViewModel()
        {
            // 加载设置
            _settings = AppSettings.Load();
            
            _indexFilePath = Path.Combine(_packsPath, INDEX_FILE_NAME);
            LoadTargets();

            // 恢复上次的设置
            _selectedTarget = _settings.SelectedTarget;
            _selectedInterfaceIndex = _settings.SelectedInterfaceIndex;
            _selectedSpeedIndex = _settings.SelectedSpeedIndex;
            _selectedFilePath = _settings.SelectedFilePath ?? "";
            _programAddress = _settings.ProgramAddress;

            ShowFileSelectDialog = new Interaction<Unit, string?>();

            DownloadCommand = ReactiveCommand.Create(OnDownload);
            OpenFileCommand = ReactiveCommand.Create(OnOpenFile);
            EraseChipCommand = ReactiveCommand.Create(OnEraseChip);
            ReadFullChipCommand = ReactiveCommand.Create(OnReadFullChip);
            ReadPartialChipCommand = ReactiveCommand.Create(OnReadPartialChip);
            SaveAsCommand = ReactiveCommand.Create(OnSaveAs);

            // 添加模式切换命令
            SwitchModeCommand = ReactiveCommand.Create(() =>
            {
                IsAdvancedMode = !IsAdvancedMode;
            });

            // 默认为简单模式
            IsAdvancedMode = false;
        }

        private void LoadTargets()
        {
            // 确保packs目录存在
            Directory.CreateDirectory(_packsPath);

            // 加载或创建索引
            LoadOrCreateIndex();

            // 检查新增的pack文件
            UpdateIndexWithNewPacks();
        }

        private void LoadOrCreateIndex()
        {
            if (File.Exists(_indexFilePath))
            {
                try
                {
                    var json = File.ReadAllText(_indexFilePath);
                    _targetIndex = JsonSerializer.Deserialize<Dictionary<string, string>>(json, AppJsonSerializerContext.Default.DictionaryStringString) ?? [];
                }
                catch
                {
                    _targetIndex = new Dictionary<string, string>();
                }
            }
        }

        private void UpdateIndexWithNewPacks()
        {
            var packExtracter = new PackExtracter();
            bool indexChanged = false;

            // 获取所有.pack文件
            var packFiles = Directory.GetFiles(_packsPath, "*.pack");
            
            foreach (var packPath in packFiles)
            {
                // 检查这个pack文件中的targets是否已经在索引中
                var targetNames = packExtracter.ExtractTargetNames(packPath);
                foreach (var targetName in targetNames)
                {
                    if (!_targetIndex.ContainsKey(targetName))
                    {
                        _targetIndex[targetName] = Path.GetFileName(packPath);
                        indexChanged = true;
                    }
                }
            }

            // 如果索引有更新，保存到文件
            if (indexChanged)
            {
                SaveIndex();
            }

            var sortedTargetNames = _targetIndex.Keys.ToList();

            // 从BuiltInTargets中获取targets并与sortedTargetNames合并
            sortedTargetNames.AddRange(BuiltInTargets.All.Keys.Where(x => !sortedTargetNames.Contains(x)));

            // 更新Targets属性
            Targets = new ObservableCollection<string>(sortedTargetNames.OrderBy(x => x));
        }

        private void SaveIndex()
        {
            var json = JsonSerializer.Serialize(_targetIndex, AppJsonSerializerContext.Default.DictionaryStringString);
            File.WriteAllText(_indexFilePath, json);
        }

        private ObservableCollection<string> _targets = new();
        public ObservableCollection<string> Targets
        {
            get => _targets;
            private set => this.RaiseAndSetIfChanged(ref _targets, value);
        }

        private async Task OnOpenFile()
        {
            var result = await ShowFileSelectDialog.Handle(Unit.Default);
            if(result != null)
            {
                await HandleFileOpen(result);
            }
        }

        public async Task HandleFileOpen(string filePath)
        {
            SelectedFilePath = filePath;
            var extension = System.IO.Path.GetExtension(filePath).ToLower();
            IsProgramAddressReadOnly = extension is ".hex" or ".elf" or ".axf";

            // 简单模式下不加载文件到HexEditor
            if (IsAdvancedMode && extension is ".bin" or ".hex")
            {
                try
                {
                    if (extension == ".bin")
                    {
                        FileContent = await File.ReadAllBytesAsync(filePath);
                        // 对于bin文件，使用用户输入的程序地址
                        if (TryParseProgramAddress(ProgramAddress, out var address))
                        {
                            ParsedProgramAddress = address;
                            BaseAddress = address;
                            // 使用CustomMemoryBinaryDocument并传入基地址
                            Document = new MemoryBinaryDocument(FileContent);
                        }
                        else
                        {
                            BaseAddress = 0;
                            Document = new MemoryBinaryDocument(FileContent);
                        }
                    }
                    else if (extension == ".hex")
                    {
                        var hexFileContent = await File.ReadAllLinesAsync(filePath);
                        var hexParser = new IntelHexParser();
                        var (startAddress, binaryData) = hexParser.ParseHexFile(hexFileContent);
                        
                        // 更新UI显示和内部状态
                        ParsedProgramAddress = startAddress;
                        ProgramAddress = $"0x{startAddress:X8}";
                        FileContent = binaryData;

                        BaseAddress = startAddress;
                        // 对于hex文件，使用从文件解析出的地址作为基地址
                        Document = new MemoryBinaryDocument(binaryData);
                        
                    }
                    IsFileLoaded = true;
                }
                catch (Exception ex)
                {
                    await MessageBox.ShowDialog($"无法加载文件: {ex.Message}");
                    FileContent = null;
                    Document = null;
                    IsFileLoaded = false;
                    ParsedProgramAddress = 0;
                }
            }
            else
            {
                FileContent = null;
                Document = null;
                IsFileLoaded = false;
                
                // 对于.hex文件，尝试解析地址信息
                if (extension == ".hex")
                {
                    try
                    {
                        var hexFileContent = await File.ReadAllLinesAsync(filePath);
                        var hexParser = new IntelHexParser();
                        var (startAddress, _) = hexParser.ParseHexFile(hexFileContent);
                        
                        ParsedProgramAddress = startAddress;
                        ProgramAddress = $"0x{startAddress:X8}";
                    }
                    catch (Exception ex)
                    {
                        await MessageBox.ShowDialog($"解析HEX文件地址失败: {ex.Message}");
                        ParsedProgramAddress = 0;
                    }
                }
                else
                {
                    ParsedProgramAddress = 0;
                }
            }
        }

        private async Task OnDownload()
        {
            try 
            {
                IsDownloading = true;
                DownloadProgress = 0;

                // 清空日志
                ClearLog();

                // Validate target selection
                if (SelectedTarget == null || string.IsNullOrEmpty(SelectedTarget))
                {
                    await MessageBox.ShowDialog("请选择器件", "提示");
                    return;
                }

                bool hasTarget = false;
                TargetBase? target = null;

                // 检查选择的器件是否存在
                if(BuiltInTargets.All.ContainsKey(SelectedTarget))
                {
                    hasTarget = true;
                    target = BuiltInTargets.All[SelectedTarget];
                    AppendLog("使用内置目标定义");
                }
                else if(_targetIndex.ContainsKey(SelectedTarget))
                {
                    // 从pack文件中提取目标
                    string packFileName = _targetIndex[SelectedTarget];
                    string packFilePath = Path.Combine(_packsPath, packFileName);
                    
                    if(File.Exists(packFilePath))
                    {
                        try 
                        {
                            target = PackExtracter.ExtractTarget(packFilePath, SelectedTarget);
                            if(target != null)
                            {
                                hasTarget = true;
                                AppendLog($"从pack文件加载目标定义: {packFileName}");
                            }
                        }
                        catch(Exception ex)
                        {
                            AppendLog($"从pack文件加载目标失败: {ex.Message}");
                            await MessageBox.ShowDialog($"加载目标失败：{ex.Message}", "错误");
                            return;
                        }
                    }
                    else
                    {
                        AppendLog($"找不到pack文件: {packFileName}");
                        await MessageBox.ShowDialog($"找不到pack文件：{packFileName}", "错误");
                        return;
                    }
                }

                if(!hasTarget || target == null)
                {
                    await MessageBox.ShowDialog("找不到目标定义", "错误");
                    return;
                }

                AppendLog($"选择的器件: {SelectedTarget}");

                // Validate file path
                if (string.IsNullOrWhiteSpace(SelectedFilePath))
                {
                    await MessageBox.ShowDialog("请选择文件", "提示");
                    return;
                }

                AppendLog($"选择的文件: {SelectedFilePath}");

                // 获取文件扩展名并转换为小写
                string extension = System.IO.Path.GetExtension(SelectedFilePath).ToLower();
                
                // 验证文件扩展名
                if (!IsValidFileExtension(extension))
                {
                    await MessageBox.ShowDialog("不支持的文件格式，仅支持 .bin、.hex、.elf 和 .axf 格式", "提示");
                    return;
                }

                // Validate program address
                if (!TryParseProgramAddress(ProgramAddress, out var parsedAddress))
                {
                    await MessageBox.ShowDialog("程序地址格式无效", "提示");
                    return;
                }

                ParsedProgramAddress = parsedAddress;

                try
                {
                    switch (extension)
                    {
                        case ".bin":
                            await DownloadBinFile(target);
                            break;
                        case ".hex":
                            await DownloadHexFile(target);
                            break;
                        case ".elf":
                        case ".axf":
                            await DownloadElfFile();
                            break;
                    }
                }
                catch (Exception ex)
                {
                    AppendLog($"错误: {ex.Message}");
                    await MessageBox.ShowDialog($"下载失败：{ex.Message}", "错误");
                }
            }
            finally
            {
                IsDownloading = false;
                DownloadProgress = 0;
            }
        }

        private bool IsValidFileExtension(string extension)
        {
            return extension switch
            {
                ".bin" or ".hex" or ".elf" or ".axf" => true,
                _ => false
            };
        }

        private void UpdateDownloadProgress(double progress)
        {
            DownloadProgress = Math.Clamp(progress, 0, 100);
        }

        private async Task<(CortexM cpu, TargetBase target)> InitializeDeviceAndTarget()
        {
            // Validate target selection
            if (SelectedTarget == null || string.IsNullOrEmpty(SelectedTarget))
            {
                throw new Exception("请选择器件");
            }

            bool hasTarget = false;
            TargetBase? target = null;

            // 检查选择的器件是否存在
            if(BuiltInTargets.All.ContainsKey(SelectedTarget))
            {
                hasTarget = true;
                target = BuiltInTargets.All[SelectedTarget];
                AppendLog("使用内置目标定义");
            }
            else if(_targetIndex.ContainsKey(SelectedTarget))
            {
                // 从pack文件中提取目标
                string packFileName = _targetIndex[SelectedTarget];
                string packFilePath = Path.Combine(_packsPath, packFileName);
                
                if(File.Exists(packFilePath))
                {
                    target = PackExtracter.ExtractTarget(packFilePath, SelectedTarget);
                    if(target != null)
                    {
                        hasTarget = true;
                        AppendLog($"从pack文件加载目标定义: {packFileName}");
                    }
                }
                else
                {
                    throw new Exception($"找不到pack文件：{packFileName}");
                }
            }

            if(!hasTarget || target == null)
            {
                throw new Exception("找不到目标定义");
            }

            AppendLog($"选择的器件: {SelectedTarget}");

            var daplinks = DapAccessCmsisDap.GetConnectedDevices();
            var daplink = daplinks.FirstOrDefault();

            if (daplink == null)
            {
                throw new Exception("未找到DAPLink设备，请检查设备连接");
            }

            daplink.Open();
            daplink.Close();
            daplink.Open();

            // 设置clock
            int speed = GetSelectedSpeed();
            daplink.SetClock(speed);
            AppendLog($"设置时钟频率: {speed/1000}kHz");

            var dp = new DebugPort(daplink);
            dp.Init();
            dp.PowerUpDebug();

            var discovery = new Discovery(dp);
            discovery.Discover();

            var ap = dp.Aps.Values.First();

            var cpu = new CortexM(daplink, dp, ap);
            cpu.ReadCoreType();

            return (cpu, target);
        }

        private async Task OnEraseChip()
        {
            try 
            {
                IsDownloading = true;
                DownloadProgress = 0;
                ClearLog();

                await Task.Run(async () =>
                {
                    try
                    {
                        var (cpu, target) = await InitializeDeviceAndTarget();

                        var flash = new FlashMemory(cpu, target);
                        flash.Init(FlashOperations.ERASE);

                        flash.ProgressCallback = (current, total) =>
                        {
                            UpdateDownloadProgress((double)current / total * 100);
                        };

                        flash.AppendLog = (message) =>
                        {
                            AppendLog(message);
                        };

                        AppendLog("开始整片擦除...");
                        flash.EraseChip();
                        AppendLog("整片擦除完成");

                        flash.Cleanup();
                        cpu.Reset();
                    }
                    catch
                    {
                        UpdateDownloadProgress(0);
                        throw;
                    }
                });
            }
            catch (Exception ex)
            {
                AppendLog($"错误: {ex.Message}");
                await MessageBox.ShowDialog($"擦除失败：{ex.Message}", "错误");
            }
            finally
            {
                IsDownloading = false;
                DownloadProgress = 0;
            }
        }

        private async Task ProgramBin(TargetBase target, byte[] binary, uint startAddress)
        {
            int speed = 1000000;

            switch(SelectedSpeedIndex)
            {
                case 0:
                    speed = 100000;
                    break;
                case 1:
                    speed = 500000;
                    break;
                case 2:
                    speed = 1000000;
                    break;
                case 3:
                    speed = 4000000;
                    break;
            }

            await Task.Run(() =>
            {
                try
                {
                    var daplinks = DapAccessCmsisDap.GetConnectedDevices();
                    var daplink = daplinks.FirstOrDefault();

                    if (daplink == null)
                    {
                        throw new Exception("未找到DAPLink设备，请检查设备连接");
                    }

                    // AppendLog($"找到DAPLink设备: {daplink.SerialNumber}");
                    
                    daplink.Open();
                    daplink.Close();
                    daplink.Open();

                    // 设置clock
                    daplink.SetClock(speed);
                    AppendLog($"设置时钟频率: {speed/1000}kHz");

                    var dp = new DebugPort(daplink);
                    dp.Init();
                    dp.PowerUpDebug();

                    var discovery = new Discovery(dp);
                    discovery.Discover();
                    var ap = dp.Aps.Values.First();

                    var cpu = new CortexM(daplink, dp, ap);
                    cpu.ReadCoreType();

                    var startTime = DateTime.Now;

                    var flash = new FlashMemory(cpu, target);
                    flash.Init(FlashOperations.PROGRAM);

                    // 设置进度回调
                    flash.ProgressCallback = (current, total) =>
                    {
                        double progress = (double)current / total * 100;
                        UpdateDownloadProgress(progress);
                    };

                    // 设置日志回调
                    flash.AppendLog = (message) =>
                    {
                        AppendLog(message);
                    };

                    // 加载数据
                    flash.Program(binary, startAddress);

                    flash.Cleanup();

                    cpu.Reset();
                    
                    // 确保进度条到达100%
                    UpdateDownloadProgress(100);

                    // 打印下载耗时的时间，精确到毫秒
                    AppendLog($"下载耗时: {DateTime.Now.Subtract(startTime).TotalMilliseconds}ms");
                }
                catch
                {
                    UpdateDownloadProgress(0);
                    throw;
                }
            });
        }

        private async Task DownloadBinFile(TargetBase target)
        {
            // 验证程序地址是否已设置，因为bin文件必须指定程序地址
            if (ParsedProgramAddress == 0)
            {
                await MessageBox.ShowDialog("BIN文件下载需要指定有效的程序地址", "提示");
                return;
            }

            AppendLog($"开始下载BIN文件：{SelectedFilePath}\n程序地址：0x{ParsedProgramAddress:X8}");

            // 实现BIN文件下载逻辑
            var binary = await File.ReadAllBytesAsync(SelectedFilePath);
            AppendLog($"文件大小: {binary.Length} 字节");
            
            await ProgramBin(target, binary, ParsedProgramAddress);
            AppendLog("下载完成");
        }

        private async Task DownloadHexFile(TargetBase target)
        {
            try
            {         
                var hexFileContent = await File.ReadAllLinesAsync(SelectedFilePath);
                var hexParser = new IntelHexParser();
                var (startAddress, binaryData) = hexParser.ParseHexFile(hexFileContent);

                ParsedProgramAddress = startAddress;
                AppendLog($"开始下载HEX文件：{SelectedFilePath}\n程序地址：0x{ParsedProgramAddress:X8}\n数据大小：{binaryData.Length} 字节");

                await ProgramBin(target, binaryData, ParsedProgramAddress);
            }
            catch (Exception ex)
            {
                AppendLog($"下载HEX失败: {MethodBase.GetCurrentMethod()?.Name}: {ex}");
            }
        }

        private async Task DownloadElfFile()
        {
            AppendLog($"开始下载{Path.GetExtension(SelectedFilePath).ToUpper()}文件");
            AppendLog($"文件路径: {SelectedFilePath}");
            // TODO: 实现ELF/AXF文件下载逻辑
            // ELF/AXF文件包含程序地址信息，不需要额外指定
            AppendLog("下载完成");
        }

        private int _selectedInterfaceIndex = 0;

        public int SelectedInterfaceIndex
        {
            get => _selectedInterfaceIndex;
            set => this.RaiseAndSetIfChanged(ref _selectedInterfaceIndex, value);
        }

        private int _selectedSpeedIndex = 2;

        public int SelectedSpeedIndex
        {
            get => _selectedSpeedIndex;
            set => this.RaiseAndSetIfChanged(ref _selectedSpeedIndex, value);
        }

        // 添加保存设置的方法
        public void SaveSettings()
        {
            _settings.SelectedTarget = SelectedTarget;
            _settings.SelectedInterfaceIndex = SelectedInterfaceIndex;
            _settings.SelectedSpeedIndex = SelectedSpeedIndex;
            _settings.SelectedFilePath = SelectedFilePath;
            _settings.ProgramAddress = ProgramAddress;
            
            _settings.Save();
        }

        private int GetSelectedSpeed()
        {
            return SelectedSpeedIndex switch
            {
                0 => 100000,
                1 => 500000,
                2 => 1000000,
                3 => 4000000,
                _ => 1000000
            };
        }

        // 添加菜单命令
        public ReactiveCommand<Unit, Task> SaveAsCommand { get; }
        public ReactiveCommand<Unit, Task> ReadFullChipCommand { get; }
        public ReactiveCommand<Unit, Task> ReadPartialChipCommand { get; }

        private async Task OnSaveAs()
        {
            if (FileContent == null || !IsFileLoaded)
            {
                await MessageBox.ShowDialog("没有可以保存的数据", "提示");
                return;
            }
            
            try
            {
                await SaveReadDataAsync(ParsedProgramAddress, FileContent);
            }
            catch (Exception ex)
            {
                AppendLog($"保存文件时出错: {ex.Message}");
                await MessageBox.ShowDialog($"保存失败: {ex.Message}", "错误");
            }
        }

        private async Task OnReadFullChip()
        {
            try 
            {
                IsDownloading = true;
                DownloadProgress = 0;
                ClearLog();

                AppendLog("开始整片读取芯片...");

                await Task.Run(async () =>
                {
                    try
                    {
                        // 初始化设备和目标
                        var (cpu, target) = await InitializeDeviceAndTarget();

                        // 获取Flash区域信息
                        var flash = target.MemoryMap.Regions.FirstOrDefault(x => x.MemoryType == MemoryType.FLASH) as FlashRegion;
                        if (flash == null)
                        {
                            throw new Exception("未找到Flash区域");
                        }

                        AppendLog($"Flash区域: 起始地址 0x{flash.Start:X8}, 大小 {flash.Length} 字节");

                        // 读取整个Flash
                        await ReadChipDataAsync(cpu, target, flash.Start, (uint)flash.Length);
                    }
                    catch
                    {
                        UpdateDownloadProgress(0);
                        throw;
                    }
                });
            }
            catch (Exception ex)
            {
                AppendLog($"错误: {ex.Message}");
                await MessageBox.ShowDialog($"读取失败：{ex.Message}", "错误");
            }
            finally
            {
                IsDownloading = false;
                DownloadProgress = 0;
            }
        }

        private async Task OnReadPartialChip()
        {
            try
            {
                // 弹出对话框要求用户输入起始地址和长度
                var result = await InputDialog.ShowDialog(
                    "读取部分芯片内容",
                    "起始地址 (十六进制, 如: 0x8000000):",
                    "读取长度 (十进制, 字节数):",
                    ProgramAddress, // 默认使用当前程序地址作为起始地址
                    "4096" // 默认读取4KB
                );

                if (!result.Success)
                {
                    return; // 用户取消
                }

                // 解析输入
                if (!TryParseProgramAddress(result.Value1, out uint startAddress))
                {
                    await MessageBox.ShowDialog("起始地址格式无效，请输入有效的十六进制地址", "输入错误");
                    return;
                }

                if (!uint.TryParse(result.Value2, out uint length) || length == 0)
                {
                    await MessageBox.ShowDialog("读取长度格式无效，请输入有效的正整数", "输入错误");
                    return;
                }

                // 限制最大读取长度为4MB
                if (length > 4 * 1024 * 1024)
                {
                    await MessageBox.ShowDialog("读取长度过大，请不要超过4MB (4194304字节)", "输入错误");
                    return;
                }

                IsDownloading = true;
                DownloadProgress = 0;
                ClearLog();

                AppendLog($"开始读取芯片部分内容...");
                AppendLog($"起始地址: 0x{startAddress:X8}");
                AppendLog($"读取长度: {length} 字节");

                await Task.Run(async () =>
                {
                    try
                    {
                        // 初始化设备和目标
                        var (cpu, target) = await InitializeDeviceAndTarget();
                        
                        // 读取指定区域的数据
                        await ReadChipDataAsync(cpu, target, startAddress, length);
                    }
                    catch
                    {
                        UpdateDownloadProgress(0);
                        throw;
                    }
                });
            }
            catch (Exception ex)
            {
                AppendLog($"错误: {ex.Message}");
                await MessageBox.ShowDialog($"读取失败：{ex.Message}", "错误");
            }
            finally
            {
                IsDownloading = false;
                DownloadProgress = 0;
            }
        }

        private async Task ReadChipDataAsync(CortexM cpu, TargetBase target, uint startAddress, uint length)
        {
            int max_chunk_size = (int)target.FlashAlgo.PageSize; // 每次最多读取1KB数据
            
            // 计算读取所需的页数
            int pages = (int)((length + max_chunk_size - 1) / max_chunk_size);
            byte[] chipData = new byte[length];
            int readBytes = 0;

            for (int i = 0; i < pages; i++)
            {
                // 计算当前页的大小和地址
                uint currentAddr = startAddress + (uint)(i * max_chunk_size);
                int currentPageSize = (int)Math.Min(max_chunk_size, length - (i * max_chunk_size));
                int words = (currentPageSize + 3) / 4; // 向上取整到最接近的4字节

                // 读取当前页
                var pageWords = cpu.ReadMemoryBlock32(currentAddr, words);
                var pageData = MySoftLab.DapFlashCore.Utils.CommonUtils.U32leListToByteList(pageWords);

                // 复制到结果数组
                Array.Copy(pageData, 0, chipData, i * max_chunk_size, currentPageSize);
                readBytes += currentPageSize;

                // 更新进度
                double progress = (double)readBytes / length * 100;
                UpdateDownloadProgress(progress);

                AppendLog($"已读取: {readBytes}/{length} 字节 ({progress:F1}%)");
            }

            // 更新UI上的数据
            ParsedProgramAddress = startAddress;
            ProgramAddress = $"0x{startAddress:X8}";
            FileContent = chipData;
            BaseAddress = startAddress;

            // 显示在HexEditor上
            Document = new MemoryBinaryDocument(chipData);
            IsFileLoaded = true;
            
            AppendLog("读取完成，可以通过\"保存\"菜单将数据保存到文件");
        }

        private async Task SaveReadDataAsync(uint startAddress, byte[] data)
        {
            try
            {
                var topLevel = TopLevel.GetTopLevel(MainWindow.Instance);
                if (topLevel == null)
                {
                    throw new Exception("无法获取主窗口");
                }

                // 定义文件类型
                var binFileType = new FilePickerFileType("二进制文件")
                {
                    Patterns = new[] { "*.bin" },
                    MimeTypes = new[] { "application/octet-stream" }
                };
                
                var hexFileType = new FilePickerFileType("Intel HEX文件")
                {
                    Patterns = new[] { "*.hex" },
                    MimeTypes = new[] { "text/plain" }
                };

                // 打开保存文件对话框
                var saveFileDialog = await topLevel.StorageProvider.SaveFilePickerAsync(new FilePickerSaveOptions
                {
                    Title = "保存数据",
                    FileTypeChoices = new[] { binFileType, hexFileType },
                    SuggestedFileName = $"flash_dump_{startAddress:X8}.bin",
                    DefaultExtension = ".bin"
                });

                if (saveFileDialog != null)
                {
                    string filePath = saveFileDialog.Path.LocalPath;
                    string extension = Path.GetExtension(filePath).ToLower();

                    AppendLog($"保存文件: {filePath}");
                    
                    // 根据文件扩展名保存为不同格式
                    if (extension == ".hex")
                    {
                        // 保存为HEX格式
                        var hexWriter = new IntelHexWriter();
                        hexWriter.SaveToHexFile(startAddress, data, filePath);
                        AppendLog($"已保存为HEX文件，大小: {data.Length} 字节，起始地址: 0x{startAddress:X8}");
                    }
                    else
                    {
                        // 保存为BIN格式
                        await File.WriteAllBytesAsync(filePath, data);
                        AppendLog($"已保存为BIN文件，大小: {data.Length} 字节");
                    }
                    
                    await MessageBox.ShowDialog($"文件已成功保存到: {filePath}", "保存成功");
                }
            }
            catch (Exception ex)
            {
                AppendLog($"保存文件时出错: {ex.Message}");
                throw;
            }
        }
    }
}
